from fastapi import APIRouter,Depends
from sqlalchemy.orm import Session
from db.mysql import get_db
from vendor.extend.conversion import is_positive_integer,is_index_valid
from vendor.extend.courier import *
from model.downhole_sensor import GroundSensor
from model.downmine_data import DownmineData
from sqlalchemy import desc,asc,and_
from vendor.library.strain3d.stress_three import complete_stress_analysis
from dateutil.relativedelta import relativedelta
import numpy as np
import datetime
import time
from vendor.extend.conversion import is_3x3_matrix_of_numbers,is_6_by_9_grid
from model.downhole_mine import GroundMine


V3Detection = APIRouter()

@V3Detection.get('/forms')
async def forms(date_time:int=0,category:int=0,sensor_id:int=0, colliery_id:int=0,db: Session = Depends(get_db)):
    if (not isinstance(date_time, int,) or date_time<1) and category in [1,2,3]:
        return Error(msg='时间戳格式错误')
    end_time=date_time
    if category==1:
        start_time=date_time-86400
        strftime="%Y-%m-%d %H"
    elif category==2:
        start_time=date_time-604800
        strftime="%Y-%m-%d"
    elif category==3:
        # 将Unix时间戳转换为datetime对象
        dt_object = datetime.datetime.fromtimestamp(date_time)
        new_dt = dt_object - relativedelta(months=1)
        # 将结果转换回Unix时间戳
        start_time = int(new_dt.timestamp())
        strftime="%Y-%m-%d"
    else:
        end_time=int(time.time())
        start_time=end_time-86400
        strftime="%Y-%m-%d %H"




    channel_arr=[]
    stress_matrix_obj={}
    wavelength_obj={}
    transformation_matrix_obj={}
    initial_wavelengths_obj={} #初始基准波长
    coefficient_obj={} #补偿系数
    # 查找数据中的所有管道和传感器
    conditions=[]
    if is_positive_integer(colliery_id):
        conditions.append(GroundSensor.colliery_id==colliery_id)
    if is_positive_integer(sensor_id):
        conditions.append(GroundSensor.id==sensor_id)
    sensor_list=db.query(GroundSensor).filter(and_(*conditions)).all()
    if not sensor_list:
        return Error(msg='未找到相关传感器')


    drill_obj={}
    # 传入的点数
    point_num = 10
    for info in sensor_list:
        channel_num=info.chanel
        if not is_3x3_matrix_of_numbers(info.transformation_matrix):
            continue

        if not is_6_by_9_grid(info.stress_matrix):
            continue
        #钻孔信息
        mine=db.query(GroundMine).filter(GroundMine.id==info.mine_id).order_by(desc("id")).first()
        if not mine:
            continue
        #初始波长截取时间:(小时，多少个小时)
        wavelength=int(info.wavelength)
        last_data=db.query(DownmineData.create_time).filter_by(line=channel_num).order_by(asc("id")).first()
        if not last_data:
            continue

        last_info=db.query(DownmineData.data).filter(and_(DownmineData.line == channel_num,DownmineData.create_time > last_data.create_time+(wavelength*3600))).order_by(asc("id")).first()
        if not last_info:
            continue

        channel_arr.append(channel_num)
        wavelength_obj[channel_num]=int(info.wavelength)
        stress_matrix_obj[channel_num]=info.stress_matrix
        transformation_matrix_obj[channel_num]=info.transformation_matrix
        coefficient_obj[channel_num]=info.coefficient
        # 初始基准波长 (10个参数，第一个是初始温度波长，后面9个是初始应力波长)
        initial_wavelengths_obj[channel_num] = last_info.data[0:point_num]

        drill_obj[channel_num]={
            "sensor_id":info.id,
            "colliery_id":info.colliery_id,
            "mine_id":info.mine_id,
            "sensor_chanel":info.chanel,
            "sensor_number":info.sensor_number,
            "sensor_status":info.sensor_status,
            "sensor_setup_time":info.setup_time,
            'mine_serial_number':mine.serial_number
        }

    list_data=db.query(DownmineData).filter(DownmineData.create_time>start_time,DownmineData.create_time<end_time,DownmineData.line.in_(channel_arr)).order_by(asc("id")).all()
    # 传入的点数
    point_num = 10
    solution_data={} #排序数据
    sort_stress={}
    for row in list_data:
        channel_num=row.line
        if channel_num in channel_arr:
            if channel_num not in solution_data:
                solution_data[channel_num]=[]
            if channel_num not in sort_stress:
                sort_stress[channel_num]={}
            dt_object = datetime.datetime.fromtimestamp(row.create_time)
            formatted_date = dt_object.strftime(strftime)
            if formatted_date not in sort_stress[channel_num]:
                sort_stress[channel_num][formatted_date]=[]
            measured_wavelengths=row.data[0:point_num]
            initial_wavelengths=initial_wavelengths_obj[channel_num]
            KT=coefficient_obj[channel_num]
            # 原始数据（Python list 形式）传感器应变标定矩阵（9*6矩阵）：
            D_list=stress_matrix_obj[channel_num]
            #传感器坐标转换矩阵（3*3矩阵）：
            A_list=transformation_matrix_obj[channel_num]
            final_data=complete_stress_analysis(
                measured_wavelengths=measured_wavelengths,
                initial_wavelengths=initial_wavelengths,
                KT=KT,
                constitutive_matrix=D_list,
                adjustment_matrix=A_list
            )
            stress=final_data['主应力大小']
            #horizontal=final_data['正应力大小'][:3].tolist()
            solution_data[channel_num].append(stress)
            sort_stress[channel_num][formatted_date].append(stress)

    initial={}
    for row_key, row_value in sort_stress.items():
        if row_key not in initial:
            initial[row_key]={}
        for col_key, col_value in row_value.items():
            if col_key not in initial[row_key]:
                initial[row_key][col_key]=[]
                # max_values = np.amax(np.array(col_value), axis=0)
                # initial[row_key][col_key]=max_values.tolist()
                # 获得第一条最新数据
                initial[row_key][col_key]=col_value[0]


    data_list=[]
    for key_outer, inner_dict in solution_data.items():
        # 列表数据转numpy列表
        arr_with_zero = np.array(inner_dict)
        # 将None转换为nan
        arr_with_zero[arr_with_zero == None] = np.nan
        # 取每列最大值
        max_values = np.max(arr_with_zero, axis=0)
        # 转成队列
        list_max = max_values.tolist()
        # 获得第一条最新数据
        first_initial=arr_with_zero[0].tolist()
        # 数列中的None转换成0
        adjusted_array = [0 if x is None else x for x in inner_dict[-1]]
        # 使用列表推导式逐个相减
        growth_rate = [a - b for a, b in zip(first_initial, adjusted_array)]


        initial_arr={}
        chart_boj={}
        stress_max_arr={}
        growth_rate_arr={}
        for key, value in initial.items():
            if key not in chart_boj:
                chart_boj[key]={}
            for k, v in value.items():
                if k not in chart_boj[key]:
                    chart_boj[key][k]= {}

                chart_boj[key][k]={"σ1":v[0],"σ2":v[1],"σ3":v[2]}

        for index in range(3):
            stress=None
            if index in range(len(first_initial)):
                stress=first_initial[index]
            initial_arr['σ'+str((index+1))]=stress

            max_stress=None
            if index in range(len(list_max)):
                max_stress=list_max[index]
            stress_max_arr['σ'+str((index+1))]=max_stress

            rate_stress=None
            if index in range(len(growth_rate)):
                rate_stress=growth_rate[index]

            growth_rate_arr['σ'+str((index+1))]=rate_stress

        data_list.append(
            {
                'chart':chart_boj, #折线图
                'initial':initial_arr, #最新实时
                'stress_max':stress_max_arr, #每列最大值
                'growth_rate':growth_rate_arr, #增幅
                'growth_up':growth_rate_arr, #增速
                'sensor':drill_obj[key_outer]
            }
        )


    return Success(data=data_list)